using System;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// UI界面。
/// </summary>
public sealed class UIForm : MonoBehaviour, IUIForm
{
    private int m_SerialId;
    private string m_UIFormAssetName;
    private IUIGroup m_UIGroup;
    private int m_DepthInUIGroup;
    private bool m_PauseCoveredUIForm;
    private UIFormLogic m_UIFormLogic;
    public int UIFormId { get; private set; }

    // 界面导航链表节点
    /// <summary>
    /// 获取或设置前一个界面。
    /// </summary>
    public IUIForm PreviousUIForm { get; set; }

    /// <summary>
    /// 获取或设置下一个界面。
    /// </summary>
    public IUIForm NextUIForm { get; set; }

    // 子界面管理
    /// <summary>
    /// 父界面（如果当前界面是子界面）。
    /// </summary>
    public IUIForm ParentUIForm { get; set; }

    /// <summary>
    /// 子界面列表。
    /// </summary>
    private List<IUIForm> m_SubUIForms = new List<IUIForm>();

    /// <summary>
    /// 获取子界面列表。
    /// </summary>
    public IUIForm[] SubUIForms
    {
        get { return m_SubUIForms.ToArray(); }
    }

    /// <summary>
    /// 获取子界面数量。
    /// </summary>
    public int SubUIFormCount
    {
        get { return m_SubUIForms.Count; }
    }

    /// <summary>
    /// 添加子界面。
    /// </summary>
    /// <param name="subUIForm">子界面。</param>
    public void AddSubUIForm(IUIForm subUIForm)
    {
        if (subUIForm != null && !m_SubUIForms.Contains(subUIForm))
        {
            m_SubUIForms.Add(subUIForm);
            UIForm subForm = subUIForm as UIForm;
            if (subForm != null)
            {
                subForm.ParentUIForm = this;
            }
        }
    }

    /// <summary>
    /// 移除子界面。
    /// </summary>
    /// <param name="subUIForm">子界面。</param>
    public void RemoveSubUIForm(IUIForm subUIForm)
    {
        if (m_SubUIForms.Remove(subUIForm))
        {
            UIForm subForm = subUIForm as UIForm;
            if (subForm != null)
            {
                subForm.ParentUIForm = null;
            }
        }
    }

    /// <summary>
    /// 清除所有子界面。
    /// </summary>
    public void ClearSubUIForms()
    {
        foreach (IUIForm subForm in m_SubUIForms)
        {
            UIForm form = subForm as UIForm;
            if (form != null)
            {
                form.ParentUIForm = null;
            }
        }
        m_SubUIForms.Clear();
    }

    public void SetUIFormId(int id)
    {
        UIFormId = id;
    }

    /// <summary>
    /// 获取界面序列编号。
    /// </summary>
    public int SerialId
    {
        get { return m_SerialId; }
    }

    /// <summary>
    /// 获取界面资源名称。
    /// </summary>
    public string UIFormAssetName
    {
        get { return m_UIFormAssetName; }
    }

    /// <summary>
    /// 获取界面实例。
    /// </summary>
    public object Handle
    {
        get { return gameObject; }
    }

    /// <summary>
    /// 获取界面所属的界面组。
    /// </summary>
    public IUIGroup UIGroup
    {
        get { return m_UIGroup; }
    }

    /// <summary>
    /// 获取界面深度。
    /// </summary>
    public int DepthInUIGroup
    {
        get { return m_DepthInUIGroup; }
    }

    /// <summary>
    /// 获取是否暂停被覆盖的界面。
    /// </summary>
    public bool PauseCoveredUIForm
    {
        get { return m_PauseCoveredUIForm; }
    }

    /// <summary>
    /// 获取界面逻辑类。
    /// </summary>
    public UIFormLogic Logic
    {
        get { return m_UIFormLogic; }
    }

    /// <summary>
    /// 初始化界面。
    /// </summary>
    /// <param name="serialId">界面序列编号。</param>
    /// <param name="uiFormAssetName">界面资源名称。</param>
    /// <param name="uiGroup">界面所属的界面组。</param>
    /// <param name="pauseCoveredUIForm">是否暂停被覆盖的界面。</param>
    /// <param name="isNewInstance">是否是新实例。</param>
    /// <param name="userData">用户自定义数据。</param>
    public void OnInit(int serialId, string uiFormAssetName, IUIGroup uiGroup, bool pauseCoveredUIForm, bool isNewInstance, object userData)
    {
        m_SerialId = serialId;
        m_UIFormAssetName = uiFormAssetName;
        m_UIGroup = uiGroup;
        m_DepthInUIGroup = 0;
        m_PauseCoveredUIForm = pauseCoveredUIForm;

        if (!isNewInstance)
        {
            return;
        }

        m_UIFormLogic = GetComponent<UIFormLogic>();
        if (m_UIFormLogic == null)
        {
            Logger.LogErrorFormat("UIForm", "UI form '{0}' can not get UI form logic.", uiFormAssetName);
            return;
        }

#if UNITY_EDITOR
        m_UIFormLogic.OnInit(userData);
#else
            try
            {
                m_UIFormLogic.OnInit(userData);
            }
            catch (Exception exception)
            {
                Logger.LogErrorFormat("UI form '[{0}]{1}' OnInit with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception);
            }
#endif
    }

    /// <summary>
    /// 预加载界面。
    /// </summary>
    /// <param name="userData">用户自定义数据。</param>
    public void OnPreload(object userData)
    {
        if (m_UIFormLogic == null)
        {
            return;
        }

#if UNITY_EDITOR
        m_UIFormLogic.OnPreload(userData);
#else
    try
    {
        m_UIFormLogic.OnPreload(userData);
    }
    catch (Exception exception)
    {
        Logger.LogErrorFormat("UI form '[{0}]{1}' OnPreload with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception);
    }
#endif
    }

    /// <summary>
    /// 回收界面。
    /// </summary>
    public void OnRecycle()
    {
        try
        {
            m_UIFormLogic.OnRecycle();
        }
        catch (Exception exception)
        {
            Logger.LogErrorFormat("UI form '[{0}]{1}' OnRecycle with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception);
        }

        m_SerialId = 0;
        m_DepthInUIGroup = 0;
        m_PauseCoveredUIForm = true;
        
        // 清除链表关系
        PreviousUIForm = null;
        NextUIForm = null;
        
        // 清除父子关系
        ParentUIForm = null;
        ClearSubUIForms();
    }

    /// <summary>
    /// 打开界面。
    /// </summary>
    /// <param name="userData">用户自定义数据。</param>
    public void OnOpen(object userData)
    {
#if UNITY_EDITOR
        m_UIFormLogic.OnOpen(userData);
#else
                        try
            {
                m_UIFormLogic.OnOpen(userData);
            }
            catch (Exception exception)
            {
                Logger.LogErrorFormat("UI form '[{0}]{1}' OnOpen with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception);
            }
#endif
    }

    /// <summary>
    /// 关闭界面。
    /// </summary>
    /// <param name="isShutdown">是否是关闭游戏时触发。</param>
    /// <param name="userData">用户自定义数据。</param>
    public void OnClose(bool isShutdown, object userData)
    {
        try
        {
            m_UIFormLogic.OnClose(isShutdown, userData);
        }
        catch (Exception exception)
        {
            Logger.LogErrorFormat("UI form '[{0}]{1}' OnClose with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception);
        }
    }

    /// <summary>
    /// 暂停界面。
    /// </summary>
    public void OnPause()
    {
        try
        {
            m_UIFormLogic.OnPause();
        }
        catch (Exception exception)
        {
            Logger.LogErrorFormat("UI form '[{0}]{1}' OnPause with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception);
        }
    }

    /// <summary>
    /// 恢复界面。
    /// </summary>
    public void OnResume()
    {
        try
        {
            m_UIFormLogic.OnResume();
        }
        catch (Exception exception)
        {
            Logger.LogErrorFormat("UI form '[{0}]{1}' OnResume with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception);
        }
    }

    /// <summary>
    /// 界面被遮挡。
    /// </summary>
    public void OnCover()
    {
        try
        {
            m_UIFormLogic.OnCover();
        }
        catch (Exception exception)
        {
            Logger.LogErrorFormat("UI form '[{0}]{1}' OnCover with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception);
        }
    }

    /// <summary>
    /// 界面遮挡恢复。
    /// </summary>
    public void OnReveal()
    {
        try
        {
            m_UIFormLogic.OnReveal();
        }
        catch (Exception exception)
        {
            Logger.LogErrorFormat("UI form '[{0}]{1}' OnReveal with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception);
        }
    }

    /// <summary>
    /// 界面激活。
    /// </summary>
    /// <param name="userData">用户自定义数据。</param>
    public void OnRefocus(object userData)
    {
        try
        {
            m_UIFormLogic.OnRefocus(userData);
        }
        catch (Exception exception)
        {
            Logger.LogErrorFormat("UI form '[{0}]{1}' OnRefocus with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception);
        }
    }

    /// <summary>
    /// 界面轮询。
    /// </summary>
    /// <param name="elapseSeconds">逻辑流逝时间，以秒为单位。</param>
    /// <param name="realElapseSeconds">真实流逝时间，以秒为单位。</param>
    public void OnUpdate(float elapseSeconds, float realElapseSeconds)
    {
        try
        {
            m_UIFormLogic.OnUpdate(elapseSeconds, realElapseSeconds);
        }
        catch (Exception exception)
        {
            Logger.LogErrorFormat("UI form '[{0}]{1}' OnUpdate with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception);
        }
    }

    /// <summary>
    /// 界面深度改变。
    /// </summary>
    /// <param name="uiGroupDepth">界面组深度。</param>
    /// <param name="depthInUIGroup">界面在界面组中的深度。</param>
    public void OnDepthChanged(int uiGroupDepth, int depthInUIGroup)
    {
        m_DepthInUIGroup = depthInUIGroup;
        try
        {
            m_UIFormLogic.OnDepthChanged(uiGroupDepth, depthInUIGroup);
        }
        catch (Exception exception)
        {
            Logger.LogErrorFormat("UI form '[{0}]{1}' OnDepthChanged with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception);
        }
    }

    /// <summary>
    /// 前面的界面已经被关闭，当前界面重新回到当前Group的第一层时。
    /// </summary>
    public void OnReFirst()
    {
        try
        {
            m_UIFormLogic.OnReFirst();
        }
        catch (Exception exception)
        {
            Logger.LogErrorFormat("UI form '[{0}]{1}' OnReFirst with exception '{2}'.", m_SerialId, m_UIFormAssetName, exception);
        }
    }
}
